﻿// Gateway.Api 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using Aurora.AI.Common.Models;
using Aurora.AI.Wiki.Models.Videos;

namespace Aurora.AI.Wiki.Services;

public class AiVideoGenerateService(IHttpClientFactory httpClientFactory)
{
    private static readonly int API_TOKEN_TTL_SECONDS = 60 * 10;

    private IEnumerable<string> GenerateBase(AICommonSetting setting, VideoCreateRequest requestBody, string apiKey)
    {
        HttpClient client = httpClientFactory.CreateClient();
        var json = JsonSerializer.Serialize(requestBody, new JsonSerializerOptions
        {
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        });
        var data = new StringContent(json, Encoding.UTF8, "application/json");

        var request = new HttpRequestMessage
        {
            Method = HttpMethod.Post,
            Content = data,
            RequestUri = new Uri($"{(setting.CommonEndpoint).TrimEnd('/')}/v1/videos/generations"),
            Headers =
            {
                { "Authorization", apiKey }
            },
        };
        client.Timeout = TimeSpan.FromSeconds(API_TOKEN_TTL_SECONDS);
        var response = client.SendAsync(request).Result;
        var stream = response.Content.ReadAsStreamAsync().Result;
        //return stream;
        byte[] buffer = new byte[8192];
        int bytesRead;

        while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
        {
            yield return Encoding.UTF8.GetString(buffer, 0, bytesRead);
        }
    }

    private IEnumerable<string> GenerateQueryBase(AICommonSetting setting, VideoTaskQueryRequest requestBody,
        string apiKey)
    {
        HttpClient client = httpClientFactory.CreateClient();
        var json = JsonSerializer.Serialize(requestBody, new JsonSerializerOptions
        {
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        });
        var data = new StringContent(json, Encoding.UTF8, "application/json");

        var request = new HttpRequestMessage
        {
            Method = HttpMethod.Post,
            Content = data,
            RequestUri = new Uri($"{(setting.CommonEndpoint).TrimEnd('/')}/v1/videos/task/query"),
            Headers =
            {
                { "Authorization", apiKey }
            },
        };
        client.Timeout = TimeSpan.FromSeconds(API_TOKEN_TTL_SECONDS);
        var response = client.SendAsync(request).Result;
        var stream = response.Content.ReadAsStreamAsync().Result;
        //return stream;
        byte[] buffer = new byte[8192];
        int bytesRead;

        while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
        {
            yield return Encoding.UTF8.GetString(buffer, 0, bytesRead);
        }
    }


    /// <summary>
    /// create video
    /// </summary>
    /// <param name="request"></param>
    /// <param name="apiKey"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public Task<VideoCreateTaskResponse> CreateVideoAsync(AICommonSetting setting, VideoCreateRequest request,
        CancellationToken cancellationToken = default)
    {
        // var json=await GenerateBase(request, apiKey);
        // 实现接口
        StringBuilder sb = new StringBuilder();
        foreach (var str in GenerateBase(setting, request, setting.Token))
        {
            sb.Append(str);
        }

        return Task.FromResult(JsonSerializer.Deserialize<VideoCreateTaskResponse>(sb.ToString()));
    }

    /// <summary>
    /// query video
    /// </summary>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public Task<VideoCreateResponse> QueryVideoAsync(AICommonSetting setting, VideoTaskQueryRequest request,
        CancellationToken cancellationToken = default)
    {
        // 实现接口
        StringBuilder sb = new StringBuilder();
        foreach (var str in GenerateQueryBase(setting, request, setting.Token))
        {
            sb.Append(str);
        }

        return Task.FromResult(JsonSerializer.Deserialize<VideoCreateResponse>(sb.ToString()));
    }
}